package org.ysu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.ysu.mapper.*;
import org.ysu.pojo.*;
import org.ysu.service.VerifierService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
* @author libaoyu
* @description 针对表【verifier】的数据库操作Service实现
* @createDate 2024-06-17 14:59:24
*/
@Service
public class VerifierServiceImpl extends ServiceImpl<VerifierMapper, Verifier>
    implements VerifierService{
    @Resource
    VerifierMapper verifierMapper;
    @Resource
    private InterviewMapper interviewMapper;
    @Resource
    private VCadreMapper vCadreMapper;
    @Autowired
    private ClueMapper clueMapper;
    @Autowired
    private FamilyMapper familyMapper;

    @Override
    public Verifier findByIdNumber(String idNumber) {
        LambdaQueryWrapper<Verifier> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Verifier::getIdnumber,idNumber);
        Verifier verifier=verifierMapper.selectOne(wrapper);
        return verifier;
    }

    @Override
    public List<Verifier> getAllVerifier() {
        LambdaQueryWrapper<Verifier> wrapper=new LambdaQueryWrapper<>();
        List<Verifier> list=verifierMapper.selectList(wrapper);
        return list;
    }
    @Override
    public Verifier selectByVid(Integer vId){
        return verifierMapper.selectByVid(vId);
    }


    @Override
    public Statistics getInterviews(Integer data) {
        //获取所有近data天有走访记录的人员列表
        // 获取当前日期
        Date endDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String endTime = dateFormat.format(endDate);

        // 使用 Calendar 进行日期减法
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.DAY_OF_MONTH, -data + 1);
        Date startDate = calendar.getTime();
        String startTime = dateFormat.format(startDate);


//        计算天数
        Statistics statistics=new Statistics();
        LambdaQueryWrapper<Interview> wrapper=new LambdaQueryWrapper<>();
        wrapper.between(Interview::getTime,startTime+" 00:00:00",endTime+" 23:59:59");
        List<Interview> interviews=interviewMapper.selectList(wrapper);
        // 统计每个人每天的记录数
        //vcID 、 日期 、 记录数
        Map<Integer, Map<String, Integer>> personRecords = new HashMap<>();

        for (Interview interview : interviews) {
            Date interviewDate = interview.getTime(); // 获取记录的日期
            String interviewDate1 = dateFormat.format(interviewDate); //转格式
            int vcId = interview.getVcId(); // 获取记录的人员ID
            // 初始化该人员的记录统计数据
            if (!personRecords.containsKey(vcId)) {
                personRecords.put(vcId, new HashMap<>());
            }
            // 更新hash表数据
            if (!personRecords.get(vcId).containsKey(interviewDate1)) {
                personRecords.get(vcId).put(interviewDate1, 1);
            }else{
                personRecords.get(vcId).put(interviewDate1,personRecords.get(vcId).get(interviewDate1)+1);
            }
        }
        // 将结果整理为二维数组
        List<String> names = new ArrayList<>();
        List<Date> dateRange = new ArrayList<>();
        for (int i = 0; i < data; i++) {
            Date date = calendar.getTime();
            dateRange.add(date);
            calendar.add(Calendar.DAY_OF_MONTH, +1);
        }
        Integer[][] counts = new Integer[personRecords.size()][data];

        int personIndex = 0;
        for (Map.Entry<Integer, Map<String, Integer>> entry : personRecords.entrySet()) {
            int vcId = entry.getKey();
            // 根据人员ID获取姓名
            String name = vCadreMapper.getVCadre(vcId).getName();
            names.add(name);

            Map<String, Integer> records = entry.getValue();

            int dateIndex = 0;
            for (Date date : dateRange) {
                String dateString = dateFormat.format(date);
                counts[personIndex][dateIndex++] = records.getOrDefault(dateString, 0);
            }
            personIndex++;
        }
        statistics.setNames(names);
        statistics.setCounts(counts);
        return statistics;
    }

    /**
     * 获取日历数据
     * @param data
     * @return
     */
    @Override
    public CalendarData getCalendar(Integer data) {
        CalendarData calendarData=new CalendarData();
        //获取data年有记录的日期，并保存到list数组中
        List<String> date =new ArrayList<>();
        List<Integer> count=new ArrayList<>();
        //获取所有的interview中data年的日期
        LambdaQueryWrapper<Interview> wrapper=new LambdaQueryWrapper<>();
        wrapper.between(Interview::getTime,data+"-01-01",data+"-12-31");
        List<Interview> interviews=interviewMapper.selectList(wrapper);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (Interview interview : interviews) {
            Date interviewDate = interview.getTime();
            String interviewDate1 = dateFormat.format(interviewDate);
            if(!date.contains(interviewDate1)){
                date.add(interviewDate1);
                count.add(1);
            }else{
                int index=date.indexOf(interviewDate1);
                count.set(index,count.get(index)+1);
            }
        }
        calendarData.setDate(date);
        calendarData.setTimes(count);
        return calendarData;
    }

    @Override
    public StatisticData getStatistic() {
        StatisticData statisticData=new StatisticData();
    //获取今日走访记录数量
        LambdaQueryWrapper<Interview> wrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Clue> clueLambdaQueryWrapper=new LambdaQueryWrapper<>();
        Date today=new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String today1 = dateFormat.format(today);
        //大于today1最小时间，小于today1最大时间
        wrapper.between(Interview::getTime,today1+" 00:00:00",today1+" 23:59:59");
        Long count = interviewMapper.selectCount(wrapper);
        statisticData.setTodayInterviewCount(count.intValue());
    //获取今日线索数
        clueLambdaQueryWrapper.between(Clue::getCreateTime,today1+" 00:00:00",today1+" 23:59:59");
        Long clueCount = clueMapper.selectCount(clueLambdaQueryWrapper);
        statisticData.setTodayClueCount(clueCount.intValue());
    //获取可能贫困人数：返贫标准：2300
        //在interview中查找不同的fid，选择最大的time和对应的income数据，如果income数据小于2300，则记录
        BigDecimal MIN_INCOME = new BigDecimal(2300);
        LambdaQueryWrapper<Interview> interviewLambdaQueryWrapper=new LambdaQueryWrapper<>();
        //根据fid分组，按time列的值倒序排序，保留每个分组中time最大的值
        interviewLambdaQueryWrapper.select(Interview::getFId, Interview::getIncome, Interview::getTime)
                .groupBy(Interview::getFId,Interview::getTime)
                //倒序
                .orderByDesc(Interview::getTime);
        List<Interview> interviews = interviewMapper.selectList(interviewLambdaQueryWrapper);
        //对于每个分组，只留下时间最大的那个interview
        //标记每个fid是否出现过,需要处理为hash值
        //判断是否在income小于2300
        Integer poorCount=0;
        Map<Integer, Boolean> visited = new HashMap<>();
        for(int i = 0; i < interviews.size(); i++){
            //如果当前fid没有出现过，则标记为true，并计数
            if(!visited.containsKey(interviews.get(i).getFId())){
                visited.put(interviews.get(i).getFId(), true);
                if(interviews.get(i).getIncome().compareTo(MIN_INCOME)<0){
                    poorCount++;
                }
            }
       }
        statisticData.setMayPoorCount(poorCount);
    //获取Interview表和Clue表的数据和未处理的线索数
        statisticData.setInterviewCount(Math.toIntExact(interviewMapper.selectCount(null)));
        statisticData.setClueCount(Math.toIntExact(clueMapper.selectCount(null)));
        statisticData.setDisClueCount(clueMapper.getDisClueCount());
        return statisticData;
    }

    @Override
    public BarData getBarData(Integer data) {
        BarData barData=new BarData();
        //查询近data天，interview中走访人员和对应次数的数据
        //获取所有近data天有走访记录的人员列表
        // 获取当前日期
        Date endDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String endTime = dateFormat.format(endDate);

        // 使用 Calendar 进行日期减法
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.add(Calendar.DAY_OF_MONTH, -data + 1);
        Date startDate = calendar.getTime();
        String startTime = dateFormat.format(startDate);
        LambdaQueryWrapper<Interview> wrapper=new LambdaQueryWrapper<>();
        Map<Integer,Integer> mp = new HashMap<>();
        List<String> names=new ArrayList<>();
        //根据vcid分组，查询startTime和endTime之间的记录，并计算count
        wrapper.between(Interview::getTime,startTime+" 00:00:00",endTime+" 23:59:59")
                .select(Interview::getVcId,Interview::getId,Interview::getTime)
                .orderByDesc(Interview::getTime);
        List<Interview> interviews = interviewMapper.selectList(wrapper);
        //对应ids中的id和times中的次数
        for(int i = 0; i < interviews.size(); i++){
            //如果当前fid没有出现过，则标记为true，并计数
            if(!mp.containsKey(interviews.get(i).getVcId())){
                mp.put(interviews.get(i).getVcId(), 1);
            }else{
                mp.put(interviews.get(i).getVcId(), mp.get(interviews.get(i).getVcId())+1);
            }
        }
        //map根据value值排序
        List<Map.Entry<Integer, Integer>> list = new ArrayList<Map.Entry<Integer, Integer>>((Collection<? extends Map.Entry<Integer, Integer>>) mp.entrySet()); //转换为list
        Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        List<Integer> ids = new ArrayList<>();
        List<Integer> times = new ArrayList<>();
        for(int i = 0; i < list.size(); i++){
            ids.add(list.get(i).getKey());
            times.add(list.get(i).getValue());
        }
        //根据ids中的编号，查询vcadre表中对应的姓名
        for(int i = 0; i < ids.size(); i++){
            VCadre vCadre = vCadreMapper.getVCadre(ids.get(i));
            names.add(vCadre.getName());
        }
        //赋值
        barData.setNames(names);
        barData.setTimes(times);
        return barData;
    }

    @Override
    public MapData getMapData(String place) {
        //根据传来的place判断获取哪部分信息
        //如果为“nation”，则获取所有省份信息
        MapData mapData=new MapData();
        List<String> name=new ArrayList<>();
        List<Integer> value=new ArrayList<>();
        //在FAMILY中根据province列分组，计算poverty为1的个数
        Integer POVERTY=1;
        Map<String, Integer> mp=new HashMap<>();
        LambdaQueryWrapper<Family> fw=new LambdaQueryWrapper<>();
        //获取family中的所有的province
        List<String> places=new ArrayList<>();
        List<Family> families=new ArrayList<>();
        if(place.equals("nation")){
            places=familyMapper.getAllProvince();
        }else{
            //查询和province、city中哪个匹配
            fw.eq(Family::getProvince,place)
                    .groupBy(Family::getCity);
            families=familyMapper.selectList(fw);
            fw.clear();
            if(!families.isEmpty()){
                for(int i = 0; i < families.size(); i++){
                    places.add(families.get(i).getCity());
                }
            }
            else {
                fw.eq(Family::getCity,place)
                        .groupBy(Family::getCountry);
                families=familyMapper.selectList(fw);
                fw.clear();
                for(int i = 0; i < families.size(); i++){
                    places.add(families.get(i).getCountry());
                }
            }
        }
        for(int i = 0; i < places.size(); i++){
            //根据province分组，计算poverty为1的个数
            if(place.equals("nation")){
                fw.eq(Family::getProvince,places.get(i))
                        .eq(Family::getPoverty,POVERTY);
            }else{
                fw.eq(Family::getProvince,places.get(i))
                        .eq(Family::getPoverty,POVERTY)
                        .or()
                        .eq(Family::getCity,places.get(i))
                        .eq(Family::getPoverty,POVERTY)
                        .or()
                        .eq(Family::getCountry,places.get(i))
                        .eq(Family::getPoverty,POVERTY);

            }
            Integer count= Math.toIntExact(familyMapper.selectCount(fw));
            if(count!=0){
                mp.put(places.get(i),count);
            }
            fw.clear();
        }
        name=new ArrayList<>(mp.keySet());
        value=new ArrayList<>(mp.values());
        mapData.setName(name);
        mapData.setValue(value);
        return mapData;
        //为省市县获取对应的信息
    }

    @Override
    public Integer changeMaster(Integer vid1, Integer vid2) {
        return verifierMapper.changeMaster(vid1,vid2);
    }

    @Override
    public Verifier getByName(String name) {
        LambdaQueryWrapper<Verifier> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(Verifier::getName,name);
        Verifier verifier=verifierMapper.selectOne(wrapper);
        return verifier;
    }
}




